package com.winchain.chainbill.receivables.biz.mod.rx;

import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.persistence.transaction.Transaction;
import com.shell.bee.persistence.transaction.TransactionUtil;
import com.shell.framework.command.ChainBase;
import com.shell.framework.command.CommandContext;
import com.shell.framework.rx.OnErrorNotImplementedSubscriber;
import com.winchain.chainbill.basic.context.TimeoutOperation;
import com.winchain.chainbill.chain.callback.cmd.SyncConfirmCmd;
import com.winchain.chainbill.receivables.ReceivablesUtil;
import com.winchain.chainbill.receivables.base.po.ArModification;
import com.winchain.chainbill.receivables.base.po.ArOperation;
import com.winchain.chainbill.receivables.base.po.ArRecord;
import com.winchain.chainbill.receivables.base.service.ArModService;
import com.winchain.chainbill.receivables.biz.impt.cmd.ReceivablesMoveCmd;
import com.winchain.chainbill.receivables.biz.impt.cmd.ReceivablesQuotaCmd;
import com.winchain.chainbill.receivables.biz.impt.cmd.ReceivablesTranCmd;
import com.winchain.chainbill.receivables.biz.impt.rx.BatchReceivablesRevEvent;
import com.winchain.chainbill.receivables.biz.impt.rx.BatchReceivablesStats;
import com.winchain.chainbill.receivables.biz.mod.cmd.ReceivablesModCmd;
import java.math.BigDecimal;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ReceivablesModAprvPassSubscriber extends OnErrorNotImplementedSubscriber<BatchReceivablesRevEvent> {
	private final Log logger = LogFactory.getLog(getClass());
	@Autowired
	private ArModService arModService;
	@Autowired
	private ReceivablesMoveCmd receivablesMoveCmd;
	@Autowired
	private ReceivablesModCmd receivablesModCmd;
	@Autowired
	private ReceivablesQuotaCmd receivablesQuotaCmd;
	@Autowired
	private ReceivablesTranCmd receivablesTranCmd;
	@Autowired
	private SyncConfirmCmd<ArRecord> syncConfirmCmd;

	public void onApplicationEvent(final BatchReceivablesRevEvent t) {
		List<ArRecord> records = t.getRecs();
		BatchReceivablesStats stats = t.getStats();
		for (final ArRecord record : records) {
			try {
				TransactionUtil.execute(new Transaction() {
					public void doInTransaction() {
						CommandContext<ArRecord> context = new CommandContext();

						String arId = record.getArId();
						int optSeq = record.getOptSeq().intValue();

						ArOperation opt = t.getOperation();
						TimeoutOperation timeoutOpt = t.getTimeoutOperation();

						ArModification mod = ReceivablesModAprvPassSubscriber.this.arModService
								.getModByArIdAndOptSeq(arId, optSeq);
						String arStateOrig = mod.getArStateOrig();

						opt.setNextState("M");

						ArRecord newRecord = new ArRecord();
						BeanUtils.copyProperties(record, newRecord);

						BigDecimal arMoneyMod = mod.getArMoneyMod();
						BigDecimal pmtRatioMod = mod.getPmtRatioMod();
						String pmtDateMod = mod.getPmtDateMod();
						if (arMoneyMod != null) {
							newRecord.setArMoney(arMoneyMod);
						}
						if (pmtRatioMod != null) {
							newRecord.setPmtRatio(pmtRatioMod);
						}
						if (StringUtil.notEmpty(pmtDateMod)) {
							newRecord.setPmtDate(pmtDateMod);
						}
						BigDecimal creditMoneyMod = ReceivablesUtil.calcCreditMoney(newRecord.getArMoney(),
								newRecord.getConvertRatio(), newRecord.getPmtRatio());
						newRecord.setCreditMoneyOrig(record.getCreditMoney());
						newRecord.setCreditMoney(creditMoneyMod);

						context.setValue("NewRecord", newRecord);
						if (timeoutOpt != null) {
							timeoutOpt.setState(arStateOrig);
						}
						context.setSource(record);
						context.setValue("Operation", opt);
						context.setValue("TimeoutOperation", timeoutOpt);
						context.setValue("ArModification", mod);

						ChainBase<ArRecord> crb = new ChainBase();
						crb.add(ReceivablesModAprvPassSubscriber.this.receivablesMoveCmd);
						crb.add(ReceivablesModAprvPassSubscriber.this.receivablesModCmd);
						crb.add(ReceivablesModAprvPassSubscriber.this.receivablesQuotaCmd);
						crb.add(ReceivablesModAprvPassSubscriber.this.receivablesTranCmd);
						crb.add(ReceivablesModAprvPassSubscriber.this.syncConfirmCmd);
						crb.execute(context);
					}
				}, new int[0]);

				stats.addPassedRecord(record);
			} catch (Exception e) {
				e.printStackTrace();
				this.logger.error("ArRecord Mod Aprv pass error!", e);
				stats.addAbnormalRecord(record);
				stats.addAbnormalMsg(e.getMessage());
			}
		}
	}
}
